/*-
 * Copyright (C) 2018-2020, Shanghai Trusted Industry Control Platform Co., Ltd.
 * Created by 周正辉 (Zhenghui Zhou) <zhouzhenghui@ticpsh.com>, 赵楷文 (Kaiwen
 * Zhao) <zhaokaiwen@ticpsh.com>
 */

#ifndef SEARCHER_H
#define SEARCHER_H

#include <clang/AST/Decl.h>

#include <set>
#include <string>
#include <vector>

namespace rocket {
namespace common {

struct CXXRecordOpts {};

/**
 * @brief findRecord 检索在某个声明结构中是否存在拥有某个名字的C结构体声明
 * @param decl
 * @param name
 * @return
 */
clang::RecordDecl* findNamedRecord(clang::Decl* decl, std::string name);

/**
 * @brief findCXXRecord 检索在某个声明结构中是否存在拥有某个名字的CXX类声明
 * @param decl
 * @param name
 * @param opts
 * @return
 */
clang::CXXRecordDecl* findNamedCXXRecord(clang::Decl* decl, std::string name,
                                         CXXRecordOpts opts = CXXRecordOpts());

/**
 * @brief findRecordNamedBase 检索得到某个类的基类声明
 * @param decl
 * @param name
 * @return
 */
const clang::CXXRecordDecl* findRecordNamedBase(const clang::CXXRecordDecl* rd,
                                                std::string name);

const clang::CXXRecordDecl* findRecordDrivedCtor(const clang::CXXRecordDecl* rd,
                                                 std::string fname,
                                                 std::string bname);

std::set<const clang::CXXRecordDecl*> getAllRecordBases(
    const clang::CXXRecordDecl* rd);
void getAllRecordBases(const clang::CXXRecordDecl* rd,
                       std::set<const clang::CXXRecordDecl*>& bases);
std::vector<const clang::CXXRecordDecl*> getAllRecordBasesList(
    const clang::CXXRecordDecl* rd);

/**
 * @brief findFunction 检索是否存在拥有某个mangled name的函数声明
 * @param decl
 * @param mangled
 * @return
 */
clang::FunctionDecl* findMangledFunction(clang::Decl* decl,
                                         std::string mangled);

clang::FunctionTemplateDecl* findMangledFunctionTemplate(clang::Decl*,
                                                         std::string mangled);

/**
 * @brief findNamedFunctions 检索是否存在拥有某个名的CXX函数声明
 * @param decl
 * @param fname
 * @return
 */
std::set<clang::FunctionDecl*> findNamedFunctions(clang::Decl* decl,
                                                  std::string fname);

/**
 * @brief findFunction 检索是否存在拥有某个名和形参列表的CXX函数声明
 * @param decl
 * @param fname
 * @param fargts
 * @return
 */
clang::FunctionDecl* findNamedFunction(clang::Decl* decl, std::string fname,
                                       std::vector<std::string> fargts);

std::map<const clang::Type*, std::set<const clang::Expr*>>
getAllFunctionExceptions(const clang::FunctionDecl* fd);

}  // namespace common
}  // namespace rocket

#endif  // SEARCHER_H
